package com.swak.utils;

import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.util.internal.ReflectionUtil;
import sun.misc.Unsafe;

/**
 * UNSAFE.
 * 
 * @author 618lf
 */
public class UNSAFE {

	static Logger LOGGER = LoggerFactory.getLogger(UNSAFE.class);

	static final Unsafe UNSAFE;
	public static final boolean SUPPORT;

	static {

		/**
		 * 加载Unsafe
		 */
		Unsafe unsafe = null;
		try {
			final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
			ReflectionUtil.trySetAccessible(unsafeField, false);
			unsafe = (Unsafe) unsafeField.get(null);
		} catch (Throwable e) {
			unsafe = null;
			LOGGER.debug("sun.misc.Unsafe.theUnsafe: unavailable: {}", ((Throwable) e).getMessage());
		}
		UNSAFE = unsafe;
		SUPPORT = UNSAFE != null;
	}

	public static Unsafe getUnsafe() {
		return UNSAFE;
	}
	
    public static Object getObject(Object o, long offset) {
        return UNSAFE.getObject(o, offset);
    }

    public static long getLong(Object o, long offset) {
        return UNSAFE.getLong(o, offset);
    }

    public static int getInt(Object o, long offset) {
        return UNSAFE.getInt(o, offset);
    }

    public static short getShort(Object o, long offset) {
        return UNSAFE.getShort(o, offset);
    }

    public static byte getByte(Object o, long offset) {
        return UNSAFE.getByte(o, offset);
    }

    public static float getFloat(Object o, long offset) {
        return UNSAFE.getFloat(o, offset);
    }

    public static double getDouble(Object o, long offset) {
        return UNSAFE.getDouble(o, offset);
    }

    public static boolean getBoolean(Object o, long offset) {
        return UNSAFE.getBoolean(o, offset);
    }

    public static char getChar(Object o, long offset) {
        return UNSAFE.getChar(o, offset);
    }

    public static void putObject(Object o, long offset, Object x) {
        UNSAFE.putObject(o, offset, x);
    }

    public static void putInt(Object o, long offset, int x) {
        UNSAFE.putInt(o, offset, x);
    }

    public static void putLong(Object o, long offset, long x) {
        UNSAFE.putLong(o, offset, x);
    }

    public static void putFloat(Object o, long offset, float x) {
        UNSAFE.putFloat(o, offset, x);
    }

    public static void putDouble(Object o, long offset, double x) {
        UNSAFE.putDouble(o, offset, x);
    }

    public static void putShort(Object o, long offset, short x) {
        UNSAFE.putShort(o, offset, x);
    }

    public static void putByte(Object o, long offset, byte x) {
        UNSAFE.putByte(o, offset, x);
    }

    public static void putChar(Object o, long offset, char x) {
        UNSAFE.putChar(o, offset, x);
    }

    public static void putBoolean(Object o, long offset, boolean x) {
        UNSAFE.putBoolean(o, offset, x);
    }

    public static Object allocateInstance(Class<?> cls) throws InstantiationException {
        return UNSAFE.allocateInstance(cls);
    }
	
    @SuppressWarnings("deprecation")
	public static long objectFieldOffset(Field field) {
        return UNSAFE.objectFieldOffset(field);
    }
}
